package com.hong.listener.impl;

import com.hong.Config.RegisterConfig;
import com.hong.Config.RpcServerConfig;
import com.hong.RpcServer;
import com.hong.listener.RpcServerListener;
import com.hong.qrpc.annotation.QRpcClient;
import com.hong.qrpc.pojo.RegisterCenterConfig;
import com.hong.qrpc.register.Register;
import com.hong.qrpc.utils.StringUtils;
import com.hong.vo.ListenerCandidate;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import java.net.InetAddress;
import java.util.List;

/**
 * 该类的职责是从bean工厂中获取rpc服务的实现对象并且注册到服务端对象中以便调用
 *
 * @Author HQT
 * @Date 2022/8/1 20:31
 */
@AllArgsConstructor
@NoArgsConstructor
public class SpringRegistrar implements RpcServerListener {
    private List<Class> classes;
    private ConfigurableListableBeanFactory beanFactory;
    private RpcServer rpcServer;

    public SpringRegistrar(List<Class> classes, ConfigurableListableBeanFactory beanFactory) {
        this.classes = classes;
        this.beanFactory = beanFactory;
    }

    @Override
    public void beforeRpcServerStart(RpcServer rpcServer) {
        this.rpcServer = rpcServer;
        for (Class clazz : classes) {
            try {
                RpcServerConfig rpcServerConfig = rpcServer.getConfigManager().getRpcServerConfig();
                RegisterConfig registerConfig = rpcServer.getConfigManager().getRegisterConfig();
                Register register = rpcServer.getRegister();
                QRpcClient annotation = (QRpcClient) clazz.getAnnotation(QRpcClient.class);
                //检查是否需要对外暴露服务
                if (registerConfig.isNeedExport() && register != null) {
                    InetAddress addr = InetAddress.getLocalHost();
                    String serverIp = addr.getHostAddress();
                    //切分获取所有注册中心的地址然后进行注册
                    String registerAddrs = registerConfig.getRegisterAddrs();
                    NacosRegister nacosRegister = new NacosRegister(register);
                    for (String registerAddr : StringUtils.splitByChars(registerAddrs, ';')) {
                        RegisterCenterConfig registerCenterConfig = new RegisterCenterConfig(
                                registerAddr, serverIp, rpcServerConfig.getPort(), annotation.serviceName()
                        );
                        nacosRegister.addRegisterCenterConfig(registerCenterConfig);
                    }
                    addListener(nacosRegister);
                }
                Object service = beanFactory.getBean(clazz);
                rpcServer.getServiceManager().register(clazz, service);
            } catch (Exception e) {

            }
        }
    }

    private void addListener(NacosRegister nacosRegister) {
        rpcServer.getListenerCandidates().add(new ListenerCandidate(RpcServerListener.class, nacosRegister));
    }
}
